/**
 * min document.getElementById
 * @method $
 */
function $(el) {
	return document.getElementById(el);
}

/**
 * delete the extra space
 * @method trim
 */
String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, '');
}

/**
 * add inline css for element
 * @method addCSS
 * @param csstxt {String} some style
 * @param el {html element} html element
 * @attention this method will overwritten the inline styles
 */
function addCSS(csstxt,el) {
	el.setAttribute('style',csstxt);
}

/**
 * translate color value to rgb
 * @method toRGB
 * @param color {String} value
 */
function toRGBA(color, alpha) {
	var span = document.createElement('span');
	span.style.color = color;
	document.body.appendChild(span);
	var ncolor = window.getComputedStyle(span, null).getPropertyValue('color');
	document.body.removeChild(span);
	var to2 = parseInt(('0x' + ncolor.slice(1)), 16);
	var r = to2 >> 16,
	//g = parseInt('0000000000000000' + (to2 >> 8).toString(2).slice(-8),2),
	g = (to2 & 0x00ff00) >> 8,
	//b = parseInt('0000000000000000' + to2.toString(2).slice(-8),2);
	b = to2 & 0x0000ff;
	return ('rgba(' + [r, g, b, alpha].join(',') + ')');
}

/**
 * min or max the rule by animation
 * @method animation
 * @param el {html element} the canvas
 * @param func {Function} the func to execute
 * @param sign {Number} number sign
 * @param callback {Function} callback
 */
function animation(el,func,sign,callback) {
	var w = el.width,h = el.height,
	b = w > h,
	delay = 10,
	_w = sign > 0 ? 40 : w,
	_h = sign > 0 ? 40 : h;
	setTimeout(function() {
		var n = Math.min(_w,_h),
		_n = sign > 0 ? (n < 80) : (n > 40);
		if(_n) {
			if(b) {
				_w += Math.ceil(w*sign/10);
				_h += 1*sign;
			} else {
				_h += Math.ceil(h*sign/10);
				_w += 1*sign;
			}
			func(_w,_h);
			setTimeout(arguments.callee, delay);
		} else {
			sign > 0 ? func(w,h) : func(40,40);
			callback && callback();
		}
	},delay);
}

/**
 * draw the ruler background
 * @method drawRluer
 * @param canvas {html element} the canvas element
 * @param isver {Boolean} is vertical or horizontal
 * @param data {Array} the gradient data,contain start color,end color and length
 * @param size {Array} the width and height
 */
function drawRuler(canvas, isver, data, size) {
	var cxt = canvas.getContext('2d');
	cxt.clearRect(0, 0, canvas.width, canvas.height);
	//set canvas w & h,create gradient
	if (isver) {
		canvas.height = size[1];
		canvas.width = 80;
		var gradient = cxt.createLinearGradient(30, 0, data[2] * 1 + 30, 0);
	} else {
		canvas.width = size[0];
		canvas.height = 80;
		var gradient = cxt.createLinearGradient(0, 30, 0, data[2] * 1 + 30);
	}
	gradient.addColorStop(0, data[0]);
	gradient.addColorStop(1, data[1]);
	cxt.fillStyle = gradient;
	//begin draw
	cxt.beginPath();
	if (isver) {
		cxt.arc(40, 30, 30, Math.PI, Math.PI * 2, false);
		cxt.rect(10, 30, 60, size[1]);
	} else {
		cxt.arc(30, 40, 30, Math.PI / 2, Math.PI * 3 / 2, false);
		cxt.rect(30, 10, size[0], 60);
	}
	cxt.fill();
}

/**
 * main func,load all event
 * @method window.onload
 */
window.addEventListener("load", function() {
	var w = screen.availWidth + 70,
	h = screen.availHeight + 70,
	//get background-color and alpha
	ca = (widget.preferenceForKey('style') || 'red|0.8|orange|0.6|50').split('|'),
	//body
	db = document.body,
	//canvas
	canvas = $('J_Canvas'),
	//ruler and inner
	ruler = $('ruler'),
	operate = $('J_Operate'),
	pre = $('J_Pre'),
	middle = $('J_Middle'),
	next = $('J_Next'),
	//guide and inner
	guide = $('J_Guide'),
	gnum = $('J_GNum'),
	//color and inner
	color = $('J_Color'),
	bgcolor = $('J_BgColor'),
	calpha = $('J_Alpha'),
	cbtn = $('J_ChangeSure'),
	cancel = $('J_CancelSet'),
	//prepare for innerhtml
	inner = '',
	line = '',
	//is first set 
	isFirst = true,
	//log isVer
	isVer = false,
	//defined some literal
	SIZE = [w, h],
	DATA = [toRGBA(ca[0], ca[1]), toRGBA(ca[2], ca[3]), ca[4]];

	//create horizontal canvas
	drawRuler(canvas, isVer, DATA, SIZE);
	//init style
	window.resizeTo(w, 80);
	window.moveTo(0, 80);

	//fill the line
	for (var i = 0; i < w - 70; i++) {
		inner += '<span' + (i % 2 == 0 ? (' class="' + (i % 10 == 0 ? 'l': (i % 4 == 0 ? 'm': 's')) + '"') : '') + '></span>';
	}
	pre.innerHTML = inner,
	next.innerHTML = inner;

	//fill the num
	for (var j = 0; j < (w - 70) / 100; j++) {
		line += '<b>' + j * 100 + '</b>';
	}
	middle.innerHTML = line;

	/**
	 * add move event for document
	 */
	document.addEventListener('mousemove', function(e) {
		if (!isVer) {
			var l = e.clientX;
			if (l < 70) {
				guide.style.visibility = 'hidden';
			} else {
				gnum.innerHTML = parseInt(l) - 70;
				addCSS('left:' + parseInt(l) + 'px', guide);
				var _os = gnum.offsetWidth / 2,
				_ml = (w - l) < _os ? (_os*2 - (w - l) + 1) : _os;
				addCSS('margin-left:-' + _ml + 'px',gnum);
			}
		} else {
			var t = e.clientY;
			if (t < 70) {
				guide.style.visibility = 'hidden';
			} else {
				gnum.innerHTML = parseInt(t) - 70;
				addCSS('top:' + parseInt(t) + 'px', guide);
				addCSS('top:-' + ((h - t) < 10 ? (17 - (h - t)) : 10) + 'px',gnum);
			}
		}
	},
	false);

	/**
	 * move by dir key
	 */
	document.addEventListener('keypress', function(e) {
		var kcode = e.keyCode;
		switch (kcode * 1) {
		case 37:
			window.moveBy( - 1, 0);
			break;
		case 38:
			window.moveBy(0, - 1);
			break;
		case 39:
			window.moveBy(1, 0);
			break;
		case 40:
			window.moveBy(0, 1);
			break;
		}
	},
	false);

	/**
 	  * change the canvas gradient 
  	  * @method changeColor
  	  * @param el {html elemnt} the set block
      * @param type {String} set type,change | show
  	  * @param id {String} canvas id
  	  * @param size {Array} canvas size,width & height
  	  * @param colors {Array} colors
  	  */
	function changeColor(el, type, id) {
		var inputs = el.getElementsByTagName('input');
		if (type == 'change') {
			var color1 = toRGBA(inputs[0].value, inputs[1].value),
			color2 = toRGBA(inputs[2].value, inputs[3].value);
			//overwritten the canvas
			DATA = [color1, color2, inputs[4].value];
			drawRuler(canvas, isVer, DATA, SIZE);
			//write to the key
			widget.setPreferenceForKey(inputs[0].value + '|' + inputs[1].value + '|' + inputs[2].value + '|' + inputs[3].value + '|' + inputs[4].value, 'style');
			el.style.display = 'none';
		} else {
			el.style.display = 'block';
			if (isFirst) {
				for (var i = 0; i < inputs.length; i++) {
					inputs[i].value = ca[i];
				}
			}
			isFirst = false;
		}
	}
	cbtn.addEventListener('click', function() {
		var id = isVer ? 'C_Ver': 'C_Hor';
		changeColor(color, 'change', id);
	},
	false);

	/**
	 * hide color set
	 */
	cancel.addEventListener('click', function() {
		color.style.display = 'none';
	},
	false);

	/**
	 * add set ruler event
	 */
	operate.addEventListener('click', function(e) {
		var target = e.target,
		cname = target.className;
		switch (cname) {
		case 'o-change':
			changeColor(color, 'show');
			break;
		case 'o-dir':
			changeDir();
			break;
		case 'o-close':
			window.close();
			break;
		case 'o-min':
			animation(canvas,window.resizeTo,-1,function() {
				target.className = 'o-max';
			});
			break;
		case 'o-max':
			animation(canvas,window.resizeTo,1,function() {
				target.className = 'o-min';
			});
			break;			
		}
	},
	false);

	/**
  	  * change the dirction of the ruler
  	  * @method changeDir
  	  */
	function changeDir() {
		drawRuler(canvas, ! isVer, DATA, SIZE);
		if (!isVer) {
			db.className = 'ver';
			window.resizeTo(80, h);
			this.title = 'Horizontal';
			isVer = true;
		} else {
			db.removeAttribute('class');
			window.resizeTo(w, 80);
			this.title = 'Vertical';
			isVer = false;
		}
	}
},
false);

